#ifndef LW_MQTT_H
#define LW_MQTT_H

#ifdef __cplusplus
extern "C" {
#endif

// Only include MQTT headers if ENABLE_MQTT is defined
#ifdef ENABLE_MQTT
#include "mqtt.h"
#include "mqtt_pal.h"
#endif

#ifdef __cplusplus
}
#endif

// Only define C++ class if ENABLE_MQTT is defined and we're compiling C++
#if defined(__cplusplus) && defined(ENABLE_MQTT)

#include <string>
#include <functional>

class LwMqtt {
public:
    // Callback type for message handling
    typedef std::function<void(const std::string& topic, const std::string& payload)> MessageCallback;

    /**
     * @brief Constructor for LwMqtt
     */
    LwMqtt();

    /**
     * @brief Destructor for LwMqtt
     */
    ~LwMqtt();

    /**
     * @brief Initialize MQTT client
     * @param host MQTT broker host
     * @param port MQTT broker port
     * @param client_id Client identifier
     * @return true if initialization successful, false otherwise
     */
    bool init(const std::string& host, int port, const std::string& client_id);

    /**
     * @brief Deinitialize MQTT client
     */
    void deinit();

    /**
     * @brief Connect to MQTT broker
     * @return true if connection successful, false otherwise
     */
    bool connect();

    /**
     * @brief Disconnect from MQTT broker
     */
    void disconnect();

    /**
     * @brief Check if client is connected
     * @return true if connected, false otherwise
     */
    bool isConnected() const;

    /**
     * @brief Publish a message to a topic
     * @param topic Topic to publish to
     * @param payload Message payload
     * @param qos Quality of service (0, 1, or 2)
     * @param retain Retain flag
     * @return true if publish successful, false otherwise
     */
    bool publish(const std::string& topic, const std::string& payload, int qos = 0, bool retain = false);

    /**
     * @brief Subscribe to a topic
     * @param topic Topic to subscribe to
     * @param qos Quality of service (0, 1, or 2)
     * @return true if subscribe successful, false otherwise
     */
    bool subscribe(const std::string& topic, int qos = 0);

    /**
     * @brief Unsubscribe from a topic
     * @param topic Topic to unsubscribe from
     * @return true if unsubscribe successful, false otherwise
     */
    bool unsubscribe(const std::string& topic);

    /**
     * @brief Set message callback function
     * @param callback Function to call when a message is received
     */
    void setMessageCallback(const MessageCallback& callback);

    /**
     * @brief Process incoming messages
     * @param timeout_ms Timeout in milliseconds
     */
    void yield(int timeout_ms = 1000);

private:
    // MQTT client state
    bool initialized_;
    bool connected_;
    std::string host_;
    int port_;
    std::string client_id_;
    int sockfd_;

    // MQTT client structure
    struct mqtt_client client_;

    // Send and receive buffers
    uint8_t sendbuf_[2048];
    uint8_t recvbuf_[2048];

    // Message callback
    MessageCallback message_callback_;

    // Static wrapper for C-style callback
    static void message_callback_wrapper(void** state, struct mqtt_response_publish *published);

    // Handle incoming message
    void handleMessage(struct mqtt_response_publish *published);
};

#endif // defined(__cplusplus) && defined(ENABLE_MQTT)

#endif // LW_MQTT_H